﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GerbilLib
{
    /// <summary>
    /// Interface for Media Items. Used for MPAA and IMDB Ratings as well as the
    /// Media Items in the Media List.
    /// </summary>
    public interface IMediaItem
    {
        /// <summary>
        /// Gets or sets the title.
        /// </summary>
        /// <value>
        /// The title.
        /// </value>
        string Title { get; set; }
        /// <summary>
        /// Gets or sets the year.
        /// </summary>
        /// <value>
        /// The year.
        /// </value>
        int Year { get; set; }
        /// <summary>
        /// Gets or sets the sort weight.
        /// </summary>
        /// <value>
        /// The sort weight.
        /// </value>
        int SortWeight { get; set; }
    }

    /// <summary>
    /// The IMediaItemEqualityComparer determines whether two IMediaItem objects are equal or not.
    /// </summary>
    public class IMediaItemEqualityComparer : IEqualityComparer<IMediaItem>
    {
        /// <summary>
        /// Determines whether the two IMediaItem objects are equal or not.
        /// </summary>
        /// <param name="x">First IMediaItem</param>
        /// <param name="y">Second IMediaItem</param>
        /// <returns>True if the title of both items is the same, otherwise false</returns>
        public bool Equals(IMediaItem x, IMediaItem y)
        {
            return x.Title == y.Title;
        }

        /// <summary>
        /// Serves as the hash function for the IMediaItemEqualityComparer type.
        /// </summary>
        /// <param name="obj">IMediaItem object</param>
        /// <returns>Hashcode for IMediaItem</returns>
        public int GetHashCode(IMediaItem obj)
        {
            return obj.GetHashCode();
        }
    }

    /// <summary>
    /// The IMediaItemEqualityComparer determines whether two IMediaItem objects are equal or not.
    /// </summary>
    public class IMediaItemSortWeightComparer : Comparer<IMediaItem>
    {
        private bool SortByNewestYear { get; set; }
        private int YearInPath { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="IMediaItemSortWeightComparer"/> class.
        /// </summary>
        /// <param name="sortByNewestYear">If set to <c>true</c> the collection will be sorted by newest year within identical title matches.</param>
        public IMediaItemSortWeightComparer(bool sortByNewestYear)
        {
            SortByNewestYear = sortByNewestYear;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="IMediaItemSortWeightComparer"/> class.
        /// </summary>
        /// <param name="sortByNewestYear">If set to <c>true</c> the collection will be sorted by newest year within identical title matches.</param>
        /// <param name="yearInPath">If set to <c>true</c> sorting by year will only take the year in the title into account.</param>
        public IMediaItemSortWeightComparer(bool sortByNewestYear, int yearInPath)
        {
            SortByNewestYear = sortByNewestYear;
            YearInPath = yearInPath;
        }

        /// <summary>
        /// When overridden in a derived class, performs a comparison of two objects of the same type and returns a value indicating whether one object is less than, equal to, or greater than the other.
        /// </summary>
        /// <param name="x">The first object to compare.</param>
        /// <param name="y">The second object to compare.</param>
        /// <returns>
        /// Value
        /// Condition
        /// Less than zero
        /// <paramref name="x"/> is less than <paramref name="y"/>.
        /// Zero
        /// <paramref name="x"/> equals <paramref name="y"/>.
        /// Greater than zero
        /// <paramref name="x"/> is greater than <paramref name="y"/>.
        /// </returns>
        /// <exception cref="T:System.ArgumentException">
        /// Type <paramref name="T"/> does not implement either the <see cref="T:System.IComparable`1"/> generic interface or the <see cref="T:System.IComparable"/> interface.
        ///   </exception>
        public override int Compare(IMediaItem x, IMediaItem y)
        {
            if (x == y) return 0;

            if (x.SortWeight.CompareTo(y.SortWeight) != 0)
                return x.SortWeight.CompareTo(y.SortWeight);
            else
                if (MediaItem.GetCleanTitle(x.Title).CompareTo(MediaItem.GetCleanTitle(y.Title)) != 0)
                    return x.Title.CompareTo(y.Title);
                else
                {
                    // TODO: Need to fill IMediaItems from small list with actual year to make this work! (Medium list working fine)
                    if (YearInPath != 0 && YearInPath == x.Year) return -1;
                    else if (YearInPath != 0 && YearInPath == y.Year) return 1;
                    
                    if (SortByNewestYear) return -x.Year.CompareTo(y.Year);
                    else return x.Year.CompareTo(y.Year);
                }
        }
    }
}
